package com.yequan.thread.countdownlatch;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author yq
 * @date 2020/09/03
 */
public class CountDownLatchDemo4 {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
//        simple();
        simpleExeTest();
    }

    private static void simpleExeTest() throws InterruptedException, ExecutionException {
        for (int i = 0; i < 10; i++) {
            List<Integer> nums = new ArrayList<>();
            nums.add(2);
            nums.add(29);
            nums.add(67);
            nums.add(43);
            nums.add(5);
            nums.add(7);
            simpleExe(nums);
        }
    }

    private static void simpleExe(List<Integer> nums) throws InterruptedException, ExecutionException {
        if (Objects.isNull(nums) || nums.size() <= 0) {
            return;
        }
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        CountDownLatch countDownLatch = new CountDownLatch(nums.size());
        List<Future<Integer>> futureList = new ArrayList<>();
        for (Integer num : nums) {
            Future<Integer> future = threadPool.submit(new CallableTask(num, countDownLatch));
            futureList.add(future);
        }
        List<Integer> numList = new ArrayList<>();
        for (Future<Integer> future : futureList) {
            numList.add(future.get());
        }
        Collections.sort(numList);
        System.out.println(numList);
        threadPool.shutdown();
    }

    public static class CallableTask implements Callable<Integer> {

        private int num;
        private CountDownLatch countDownLatch;

        public CallableTask(int num, CountDownLatch countDownLatch) {
            this.num = num;
            this.countDownLatch = countDownLatch;
        }

        @Override
        public Integer call() throws Exception {
            num++;
            Thread.sleep((long) (Math.random() * 100));
//            countDownLatch.countDown();
            System.out.println(num);
            return num;
        }
    }

    public static void simple() throws InterruptedException {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        CountDownLatch latch = new CountDownLatch(3);
        for (int i = 0; i < 3; i++) {
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("子线程" + Thread.currentThread().getName() + "开始执行任务。。。");
                        Thread.sleep((long) (Math.random() * 10000));
                        System.out.println("子线程" + Thread.currentThread().getName() + "任务执行完成。。。");
                        latch.countDown();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        System.out.println("主线程正在等待子线程执行任务。。。");
        latch.await();
        System.out.println("主线程执行任务中。。。");
        threadPool.shutdown();
    }

}
